package com.fy.utils;

import com.fy.config.FileConfig;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;

public class WordUtil {

    public static void exportWord(XWPFDocument document, HttpServletResponse response, String fileName) throws Exception{
        response.setHeader("Content-Disposition","attachment;fileName="+ fileName+".docx");
        response.setContentType("application/msword");
        OutputStream os = response.getOutputStream();
        document.write(os);
        os.flush();
        os.close();
    }

    public static String exportWord(XWPFDocument document, String fileName, FileConfig fileConfig) throws Exception{
        QrCodeUtils.mkdirs(fileConfig.getProfileSimple() + "/word/");
        FileOutputStream os = new FileOutputStream(new File(fileConfig.getProfileSimple()+ "/word/"+fileName+".doc"));
        document.write(os);
        os.flush();
        os.close();
        return fileConfig.getPre() + "/word/"+fileName+".doc";
    }


    //创建一个段落
    public static XWPFParagraph createTitleParagraph(XWPFDocument document,ParagraphAlignment paragraphAlignment,String value,int fontSize, boolean bold,int pos) {
        XWPFParagraph paragraph = document.createParagraph();    //新建一个标题段落对象（就是一段文字）
        paragraph.setAlignment(paragraphAlignment);//样式居中
        XWPFRun titleFun = paragraph.createRun();    //创建文本对象
        titleFun.setFontSize(fontSize);    //字体大小
        titleFun.setText(value);
        titleFun.setBold(bold);
        titleFun.setTextPosition(pos);//两行之间的间距
        titleFun.setFontFamily("宋体");
        return  paragraph;
    }

    //创建一个段落
    public static XWPFParagraph createParagraph(XWPFDocument document,ParagraphAlignment paragraphAlignment) {
        XWPFParagraph paragraph = document.createParagraph();    //新建一个标题段落对象（就是一段文字）
        paragraph.setAlignment(paragraphAlignment);//样式居中
        return  paragraph;
    }

    public static void createFun(XWPFParagraph paragraph,String value,int fontSize, boolean bold,int pos) {
        XWPFRun titleFun = paragraph.createRun();    //创建文本对象
        titleFun.setFontSize(fontSize);    //字体大小
        titleFun.setText(value);
        titleFun.setBold(bold);
        titleFun.setTextPosition(pos);//两行之间的间距
        titleFun.setFontFamily("宋体");
        titleFun.addBreak();
    }

    public static void createFunColor(XWPFParagraph paragraph,String value,int fontSize, boolean bold,int pos,String color) {
        XWPFRun titleFun = paragraph.createRun();    //创建文本对象
        titleFun.setFontSize(fontSize);    //字体大小
        titleFun.setText(value);
        titleFun.setBold(bold);
        titleFun.setTextPosition(pos);//两行之间的间距
        titleFun.setFontFamily("宋体");
        titleFun.setColor(color);
        titleFun.addBreak();
    }

    //创建一个段落
    public static XWPFParagraph createParagraph(XWPFDocument document,ParagraphAlignment paragraphAlignment,String value,int fontSize, boolean bold) {
        XWPFParagraph paragraph = document.createParagraph();    //新建一个标题段落对象（就是一段文字）
        paragraph.setAlignment(paragraphAlignment);//样式居中
        XWPFRun titleFun = paragraph.createRun();    //创建文本对象
        titleFun.setFontSize(fontSize);    //字体大小
        titleFun.setText(value);
        titleFun.setBold(bold);
        titleFun.setFontFamily("宋体");
        return  paragraph;
    }

    public  void createImage(XWPFDocument document,String imgPath,int width, int height) throws Exception {
        XWPFParagraph xwpfParagraph = document.createParagraph();
        XmlCursor cursor = xwpfParagraph .getCTP().newCursor();
        XWPFParagraph newPara = document.insertNewParagraph(cursor);
        newPara.setAlignment(ParagraphAlignment.LEFT);//居中
        XWPFRun newParaRun = newPara.createRun();
        newParaRun.addPicture(new FileInputStream(imgPath),XWPFDocument.PICTURE_TYPE_PNG,imgPath.substring(imgPath.lastIndexOf("/") + 1,imgPath.length()), Units.toEMU(width), Units.toEMU(height));
        document.removeBodyElement(document.getPosOfParagraph(xwpfParagraph));
    }

    public static void createTableImage(XWPFTableCell cell, ParagraphAlignment paragraphAlignment,String imgPath,int width, int height) throws Exception {
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph p = new XWPFParagraph(ctp, cell);
        p.setAlignment(paragraphAlignment);
        XWPFRun run = p.createRun();
        run.addPicture(new FileInputStream(imgPath),XWPFDocument.PICTURE_TYPE_PNG,imgPath.substring(imgPath.lastIndexOf("/") + 1,imgPath.length()), Units.toEMU(width), Units.toEMU(height));
        cell.setParagraph(p);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    }

    private static void createCellStyle(XWPFParagraph para, XWPFRun run, CTTcPr cellPr, XWPFTableCell cell, String value, int width){
        cellPr = cell.getCTTc().addNewTcPr();
        //设置宽度
        cellPr.addNewTcW().setW(BigInteger.valueOf(width));
        //第一个段落
        para = cell.getParagraphs().get(0);
        //设置对齐方式
        para.setAlignment(ParagraphAlignment.CENTER);
        para.setVerticalAlignment(TextAlignment.CENTER);
        //居中
        para.setFontAlignment(2);
        run = para.createRun();
        run.setFontSize(12);
        run.setText(value);
    }
    /**
     * 为表格插入数据，行数不够添加新行
     *
     * @param table 需要插入数据的表格
     * @param tableList 插入数据集合
     * @param index 插入开始行数
     * @param isMerge 是否合并单元格 无法适配，根据数字进行制定合并
     * @param isMerge 列数
     */
    public static void createTable(XWPFTable table, List<String[]> tableList, int index, int isMerge, int rowNums,int fontSize) {
        //创建行,根据需要插入的数据添加新行，不处理表头
        for (int i = 0; i < rowNums; i++) {
            XWPFTableRow row = table.createRow();
        }
        List<XWPFTableRow> rows = table.getRows();
        //遍历表格插入数据
        int lengthI = tableList.size();
        for (int i = 0; i < lengthI; i++) {
            List<XWPFTableCell> cells = table.getRow(i+index).getTableCells();
            int lengthJ = tableList.get(i).length;
            for (int j = 0; j < lengthJ; j++) {
                XWPFTableCell cell = cells.get(j);
                String s = tableList.get(i)[j];
                setCellParagraph(cell,s,false,ParagraphAlignment.CENTER,fontSize);
            }
        }
    }

    public static void setCellParagraph(XWPFTableCell cell, String value, boolean bold, ParagraphAlignment paragraphAlignment,int fontSize){
        CTP ctp = CTP.Factory.newInstance();
        XWPFParagraph p = new XWPFParagraph(ctp, cell);
        p.setAlignment(paragraphAlignment);
        XWPFRun run = p.createRun();
        run.setText(value);
        run.setBold(bold);
        run.setFontSize(fontSize);
        run.setFontFamily("宋体");
        cell.setParagraph(p);
        cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
    }


    //跨列合并
    public static void mergeCellsHorizontal(XWPFTable table, int row, int startCell, int endCell) {
        for (int i = startCell; i <= endCell; i++) {
            XWPFTableCell cell = table.getRow(row).getCell(i);
            if (i == startCell) {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
    // word跨行并单元格
    public static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if ( rowIndex == fromRow ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }


    public static void setTableWidthAndHAlign(XWPFTable table, String width,
                                              STJc.Enum enumValue) {
        CTTblPr tblPr = getTableCTTblPr(table);
        // 表格宽度
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        if (enumValue != null) {
            CTJc cTJc = tblPr.addNewJc();
            cTJc.setVal(enumValue);
        }
        // 设置宽度
        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);
    }

    public static CTTblPr getTableCTTblPr(XWPFTable table) {
        CTTbl ttbl = table.getCTTbl();
        // 表格属性
        CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
        return tblPr;
    }

    public static  void  setRowHeight(XWPFTable table, int height){
        List<XWPFTableRow> rows = table.getRows();

        for (XWPFTableRow row : rows) {
            CTTrPr trPr = row.getCtRow().addNewTrPr();

            CTHeight ht = trPr.addNewTrHeight();

            ht.setVal(BigInteger.valueOf(height));
        }
    }

    public static void  setCellWidth(XWPFTableCell cell, int width){
        CTTcPr tcpr = cell.getCTTc().addNewTcPr();

        CTTblWidth cellw = tcpr.addNewTcW();

        cellw.setType(STTblWidth.DXA);

        cellw.setW(BigInteger.valueOf(width));
    }

    public static void createWordXDDFChart2(XWPFDocument document, XWPFRun run, String title, String xTitle, String makeTitle, String yTitle, String[] xData, BigDecimal[]  yData, int width, int height){
        try{
            XWPFChart chart = null;
            if(run != null){
                chart = document.createChart(run,width * Units.EMU_PER_CENTIMETER, height * Units.EMU_PER_CENTIMETER);
            }else{
                chart= document.createChart(width * Units.EMU_PER_CENTIMETER, height * Units.EMU_PER_CENTIMETER);
            }

            // 标题
            chart.setTitleText(title);
            // 标题覆盖
            chart.setTitleOverlay(false);
            // 图例位置
            XDDFChartLegend legend = chart.getOrAddLegend();
            legend.setPosition(LegendPosition.TOP);

            // 分类轴标(X轴),标题位置
            XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
            bottomAxis.setTitle(xTitle);
            // 值(Y轴)轴,标题位置
            XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
            leftAxis.setTitle(yTitle);

            // CellRangeAddress(起始行号，终止行号， 起始列号，终止列号）
            // 分类轴标(X轴)数据，单元格范围位置[0, 0]到[0, 6]
            XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(xData);
            // 数据1，单元格范围位置[1, 0]到[1, 6]
            // XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, 6));
            XDDFNumericalDataSource<BigDecimal> area = XDDFDataSourcesFactory.fromArray(yData);

            // 数据1，单元格范围位置[2, 0]到[2, 6]
            // XDDFNumericalDataSource<Double> population = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, 6));

            // LINE：折线图，
            XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);

            // 图表加载数据，折线1
            XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
            // 折线图例标题
            series1.setTitle(makeTitle, null);
            // 直线
            series1.setSmooth(false);
            // 设置标记大小
            series1.setMarkerSize((short) 6);
            // 设置标记样式，星星
            series1.setMarkerStyle(MarkerStyle.STAR);

            // 绘制
            chart.plot(data);

        }catch (Exception e){
            e.printStackTrace();
        }
    }


    public static void setTableCellBorder(XWPFTable table){
        List<XWPFTableRow> rows = table.getRows();
        //遍历表格插入数据
        for (int i = 0; i < rows.size(); i++) {
            List<XWPFTableCell> cells = table.getRow(i).getTableCells();

            for (int j = 0; j < cells.size(); j++) {
                XWPFTableCell cell = cells.get(j);
                if(i==0 && i==rows.size() -1){
                    setCellBorder(cell,"dashed","1","000000",null,null,null,"dashed","1","aaaaaa",null,null,null);
                }else if(i==0){
                    setCellBorder(cell,"dashed","1","000000",null,null,null,"dashed","1","aaaaaa","dashed","1","aaaaaa");
                }else if(i == rows.size() - 1){
                    setCellBorder(cell,"dashed","1","aaaaaa","dashed","1","aaaaaa","dashed","1","aaaaaa",null,null,null);
                }else{
                    setCellBorder(cell,"dashed","1","aaaaaa","dashed","1","aaaaaa","dashed","1","aaaaaa","dashed","1","aaaaaa");
                }
            }
        }

    }
    private static void setCellBorder(XWPFTableCell cell,String lval,String lsz,String lcolor,String tval,String tsz,String tcolor,String rval,String rsz,String rcolor,String bval,String bsz,String bcolor){
        CTTcPr cellPr = cell.getCTTc().addNewTcPr();
        //设置边框
        CTTcBorders borders = cellPr.addNewTcBorders();

        CTBorder lBorder = borders.addNewLeft();
        lBorder.setVal(STBorder.Enum.forString(lval==null?"single":lval));
        lBorder.setSz(new BigInteger(lsz==null?"1":lsz));
        lBorder.setColor(lcolor==null?"000000":lcolor);

        CTBorder rBorder = borders.addNewRight();
        rBorder.setVal(STBorder.Enum.forString(rval==null?"single":rval));
        rBorder.setSz(new BigInteger(rsz==null?"1":rsz));
        rBorder.setColor(rcolor==null?"000000":rcolor);

        CTBorder tBorder = borders.addNewTop();
        tBorder.setVal(STBorder.Enum.forString(tval==null?"single":tval));
        tBorder.setSz(new BigInteger(tsz==null?"1":tsz));
        tBorder.setColor(tcolor==null?"000000":tcolor);

        CTBorder bBorder = borders.addNewBottom();
        bBorder.setVal(STBorder.Enum.forString(bval==null?"single":bval));
        bBorder.setSz(new BigInteger(bsz==null?"1":bsz));
        bBorder.setColor(bcolor==null?"000000":bcolor);
    }

}
